#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <getopt.h>
#include "headers/result.h" // Structures de données et fonction d'initialisation de celle-ci
#include "headers/affich.h" // Fonction d'affichage
#include "headers/scandir.h" // Coeur du programme : parcours des répertoire

int main(int argc, char *argv[])
{
	Resultat resultat; // Structure de données contenant l'ensemble des informations à afficher
	char **users, **groups, **groups2; // Tableaux des utilisateurs et groupes passés en paramètres
	int o, humanReadable = 0, verbose = 0; // Options de la commande
	int i; // Pour le parcours des tableaux 
	int nbUsers=0, nbGroups=0, nbGroups2=0; // Sert d'indice et de compteurs

	// Initialisation des tableaux de CC
	users = (char **) malloc(sizeof(char *));	
	groups = (char **) malloc(sizeof(char *));
	groups2 = (char **) malloc(sizeof(char *));

	// Parcours des options passées en paramètre
	while ((o = getopt(argc , argv, "u:g:G:hv")) != -1)
	{
		switch (o) {
			case 'u': // UTILISATEUR
				if(userExist(optarg) == 0){
					printf("\nUtilisateur %s inexistant \n", optarg);
					exit(1);
				}
				users[nbUsers] = (char *) malloc(strlen(optarg) * sizeof(char));
				strcpy(users[nbUsers], optarg);
				nbUsers++;
				break;
			case 'g': // GROUPE
				if(groupExist(optarg) == 0){
					printf("\nGroupe %s inexistant \n", optarg);
					exit(1);
				}
				groups[nbGroups] = (char *) malloc(strlen(optarg) * sizeof(char));
				strcpy(groups[nbGroups], optarg);
				nbGroups++;
				break;
			case 'G': // GROUPE D'UTILISATEURS
				if(groupExist(optarg) == 0){
					printf("\nGroupe %s inexistant \n", optarg);
					exit(1);
				}
				groups2[nbGroups2] = (char *) malloc(strlen(optarg) * sizeof(char));
				strcpy(groups2[nbGroups2], optarg);
				nbGroups2++;
				break;
			case 'h': // Pour l'affichage en Ko, Mo...
				humanReadable = 1;
				break;
			case 'v': // Pour l'affichage en détail par utilisateur et par groupe
				verbose = 1;
				break;
			default :
				printf("Option invalide\n");
				exit(1);
		}
	}

	resultat = malloc(sizeof(struct result));
	initResultat(&resultat, nbUsers, nbGroups, nbGroups2); // Alloue l'espace mémoire nécessaire au résultat
	
	// Pour tout les chemins : (tout les derniers arguments de la commande)

 	for(i=optind; i<=argc-1; i++)
		scanDir(&resultat, argv[i], users, groups, groups2, nbUsers, nbGroups, nbGroups2);

	// Affichage
	printf("\nCountfile :\n\n");
	if(verbose) { // On affiche le détail pour chaque groupe et utilisateur
		for(i=0; i<nbUsers; i++)
			affich("Utilisateur (-u)", users[i], resultat->infoUser[i],humanReadable);
			
		for(i=0; i<nbGroups; i++)
			affich("Groupe (-g)", groups[i], resultat->infoGroup[i],humanReadable);

		for(i=0; i<nbGroups2; i++) // Option -G
			affich("Groupe (-G)", groups2[i], resultat->infoGroup2[i], humanReadable);
	}
	affich("Résultat total","",resultat->infoTotal, humanReadable); // Affichage global
	
	// Libération de la mémoire des tableaux de CC
	for(i=0; i<nbUsers; i++) {
		free(users[i]);
		users[i] = NULL;
	}	
	for(i=0; i<nbGroups; i++) {
		free(groups[i]);
		groups[i] = NULL;
	}	
	for(i=0; i<nbGroups2; i++) {
		free(groups2[i]);
		groups2[i] = NULL;
	}
	// Libération de la mémoire de la structure resultat
	freeResultat(&resultat, nbUsers, nbGroups, nbGroups2);
	
	return 0;
}
